ICTSC2019 二次予選 問題解説: つながらなくなりました!

問題文

あなたはサーバホスティング会社に勤めているシステムエンジニアです。
顧客より、下記のとおり依頼をいただきました。

前任者退職に伴って確認しようと思いサーバ内を確認していたところ、
間違えてFWサーバとwebサーバを再起動してしまいました。
再起動前はwebページに正常にアクセスできていたのですが、アクセスできなくなってしまったため、
いい感じに直していただきたいです。

しかし、セキュリティを考えていた設定とかもあると思うので、外部アクセスなどへはそのまま利用してほしいです。
あと、監視サーバからのURL監視も通るようにしてほしいです。こちらは特に制限をかける必要はありません。
でも、サーバの担当者が出張中で認証情報がわからないので、監視サーバへはログインできないです。
また、再発しないように設定いただけると嬉しいです。

変更した設定などはコマンドレベルでご報告いただけますようお願いします。

対応してほしいところ

上記依頼に則った上で、下記を満たすように修正してください。

  • VNCから以下のwebページへHTTPアクセスが正常に通るようにしてください。
    • 対象URL: http://www.qwe.example/
    • monitorから正常に監視ができるようにしてください。
    • FWサーバ 2222番ポートへの接続で、webへssh接続できるようにしてください。
  • 構成
  • アクセス可能
    • VNC(踏み台、クライアントPCと想定してください)
    • firewall01 (192.168.0.100/10.111.100.1 admin:USerPw@19)
    • web01 (10.111.100.10 admin:USerPw@19 ※FWサーバよりアクセス可能)
  • アクセス不可
    • monitor(192.168.0.200)
      • ※ 例示用URLのため、VNCのhostsに記載して名前解決しています
      • ※ 192.168.128.0/17 のIP帯からwebサーバへのランダムアクセスを行っています。
      • 問題環境の都合上ではありますが、一般userのアクセスと考えて対応してください。

構成図

( Internet )
      |
+-----+-----+      +-----+-----+
|    VNC    |      |  Monitor  |         
+-----+-----+      +-----+-----+
      |                  |
------+------------------+------- 192.168.0.0/16
      |
+-----+-----+
|    FW     |                
+-----+-----+
      |
------+-------------------------- 10.111.100.0/24
      |
+-----+-----+
|    WEB    |                
+-----+-----+

問題解説

本問題の要件としては下記の通りです。

  • VNC – NAT(firewall) – web の通信が通らないため直す
  • Monitor(監視サーバ)からの通信を、正常に通す
  • 外部アクセス(※記載の 192.168.128.0/17)のwebアクセスを可能にした状態で、既存の攻撃対策ルールを適用する

問題文より、firewall および webを再起動してしまった影響と読み解けるので、両サーバの設定を確認します。
今回問題が発生していた箇所は両サーバのfirewall設定が永続化しておらず、
再起動したためロールバックしてしまった、というシナリオでした。不]具合が発生していた箇所を記載します。

iptables NAT設定 (FWサーバ)

入っているNAT設定は WEBサーバ(10.111.100.10)に対する SSH(22) と HTTP(80)のDNAT設定です。
DNATルールにおかしい箇所があります。

誤っている箇所

  • -A PREROUTING -s 192.168.0.100/32 -p tcp -m tcp –dport 2222 -j DNAT –to-destination 10.111.10.10:22
  • -A PREROUTING -s 192.168.0.100/32 -p tcp -m tcp –dport 80 -j DNAT –to-destination 10.111.10.10:80

通信元ポートが22/80だったアドレスを”10.111.10.10″に変換となってしまっています。(第3オクテットが違います)
下記の例の様に直すと、正しいDNAT設定となります。\
また、前任者がsaveした際にできたであろう、 /etc/sysconfig/iptables.save をリストアする事によっても正しいDNAT設定に直す事も可能です。~
※後述のFORWARDルールについてはこちらをリストアしても直っていません。

解答例

  • -A PREROUTING -s 192.168.0.100/32 -p tcp -m tcp –dport 2222 -j DNAT –to-destination 10.111.100.10:22
  • -A PREROUTING -s 192.168.0.100/32 -p tcp -m tcp –dport 80 -j DNAT –to-destination 10.111.100.10:80

これでVNCからWEBサーバに対するNATでのSSH接続が可能となります。

iptables FORWARDルール (FWサーバ)

iptablesでの攻撃対策ルールについてです。
FWサーバの各ルールは基本的に各接続許可/拒否をログ出力するように設定されています。
FWサーバ(192.168.0.100)の/var/log/messagesを見てみると下記のような出力が確認できます。

Nov 16 06:21:07 firewall01 kernel: iptables : FORWARD_ALLOW IN=eth0 OUT=eth1 SRC=192.168.0.200 DST=192.168.100.10 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=64121 DF PROTO=TCP SPT=42576 DPT=80 WINDOW=29200 RES=0x00 SYN URGP=0 
Nov 16 06:21:08 firewall01 kernel: iptables : FORWARD_ALLOW IN=eth0 OUT=eth1 SRC=192.168.0.200 DST=192.168.100.10 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=64122 DF PROTO=TCP SPT=42576 DPT=80 WINDOW=29200 RES=0x00 SYN URGP=0 
Nov 16 06:21:10 firewall01 kernel: iptables : FORWARD_ALLOW IN=eth0 OUT=eth1 SRC=192.168.0.200 DST=192.168.100.10 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=64123 DF PROTO=TCP SPT=42576 DPT=80 WINDOW=29200 RES=0x00 SYN URGP=0 
Nov 16 06:21:11 firewall01 kernel: SYN_FLOOD IN=eth0 OUT=eth1 SRC=192.168.0.200 DST=192.168.100.10 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=15639 DF PROTO=TCP SPT=42636 DPT=80 WINDOW=29200 RES=0x00 SYN URGP=0 

監視サーバ(192.168.0.200)からのアクセスがどうやらSYN_FLOODとして判定され拒否されていそうです。
FORWARDルールを確認してみます。

-A FORWARD -s 192.168.0.0/16 -p tcp -m state --state NEW -m tcp --dport 22 -j FORWARD_ALLOW
-A FORWARD -s 192.168.0.0/16 -d 10.111.100.10/32 -p tcp -m tcp --dport 80 -j SYN_CHECK
-A FORWARD -s 192.168.0.200/32 -d 10.111.100.10/32 -p tcp -m state --state NEW -m tcp --dport 80 -j FORWARD_ALLOW 
-A FORWARD ! -s 192.168.0.200/32 -d 10.111.100.10/32 -p tcp -m state --state NEW -m tcp --dport 80 -j FORWARD_ALLOW 
-A FORWARD -s 192.168.0.0/16 -d 10.111.100.10/32 -p tcp -m state --state NEW -m tcp --dport 22 -j FORWARD_ALLOW 
-A FORWARD -s 192.168.0.0/16 -d 10.111.100.10/32 -p tcp -m tcp --dport 22 -j ACCEPT 
-A FORWARD -d 10.111.100.10/32 -p tcp -m tcp --dport 443 -j FORWARD_ALLOW 
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT 

ここで気にするべき点は、iptablesの上から順にルールを読む動作です。
WEBサーバのhttpに対するアクセスをした場合、一番最初に読むFORWARDルールは

-A FORWARD -s 192.168.0.0/16 -d 10.111.100.10/32 -p tcp -m tcp –dport 80 -j SYN_CHECK

となります。

上記FORWARDルールの順だと、依頼されている

あと、監視サーバからのURL監視も通るようにしてほしいです。こちらは特に制限をかける必要はありません

にマッチせず、WEBサーバのHTTPに対するFORWARD通信はすべて下記のSYN_CHECKルールに適用されてしまいます。
SYN_CHECKルールは15秒間に5回アクセスが発生した場合一時的にアクセスを拒否する。という動作をします。
※問題用として拒否制限はかなり厳しくしてあります。

-A SYN_CHECK -p tcp -m tcp -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A SYN_CHECK -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m recent --rcheck --seconds 20 --name SYN_ATTACK --rsource -j REJECT --reject-with icmp-port-unreachable 
-A SYN_CHECK -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m recent --rcheck --seconds 15 --hitcount 5 --name SYN_sorce --rsource -j SYN_FLOOD 
-A SYN_CHECK -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m recent --set --name SYN_sorce --rsource 
-A SYN_CHECK -p tcp -m tcp -j RETURN 
-A SYN_FLOOD -m recent --set --name SYN_ATTACK --rsource -j LOG --log-prefix "iptables : SYN_FLOOD " 
-A SYN_FLOOD -j REJECT --reject-with icmp-port-unreachable 

その為、監視サーバ(192.168.0.200)のFORWARDは真っ先に許可してあげる必要があります。
下記の様に順番を入れ替えます。

-A FORWARD -s 192.168.0.0/16 -p tcp -m state --state NEW -m tcp --dport 22 -j FORWARD_ALLOW 
-A FORWARD -s 192.168.0.200/32 -d 10.111.100.10/32 -p tcp -m state --state NEW -m tcp --dport 80 -j FORWARD_ALLOW ★このルールをSYN_CHECKルールより上に入れる。
-A FORWARD -s 192.168.0.0/16 -d 10.111.100.10/32 -p tcp -m tcp --dport 80 -j SYN_CHECK 
-A FORWARD ! -s 192.168.0.200/32 -d 10.111.100.10/32 -p tcp -m state --state NEW -m tcp --dport 80 -j FORWARD_ALLOW 
-A FORWARD -s 192.168.0.0/16 -d 10.111.100.10/32 -p tcp -m state --state NEW -m tcp --dport 22 -j FORWARD_ALLOW 
-A FORWARD -s 192.168.0.0/16 -d 10.111.100.10/32 -p tcp -m tcp --dport 22 -j ACCEPT 
-A FORWARD -d 10.111.100.10/32 -p tcp -m tcp --dport 443 -j FORWARD_ALLOW 
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT 

これでFWサーバの問題点はすべて解決しました。

firewalld (webサーバ)

WEBサーバでの問題点です。
問題文の通り、依頼主はFWサーバとWEBサーバを再起動してしまっています。
その為、webサーバ側にも何か起こっている可能性があります。
今回は、firewalldの許可リストからhttpが外れている事象でした。

# systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since 土 2019-12-07 14:28:58 JST; 1 day 4h ago
     Docs: man:firewalld(1)
 Main PID: 569 (firewalld)
   CGroup: /system.slice/firewalld.service
           └─569 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid

firewalldは上がっているので、ルールを確認します。

# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

httpのアクセスが許可されていなさそうです。

その為下記のコマンドで永続許可します。
※80番ポート許可でもOKです。

# firewall-cmd --zone=public --add-service=http --permanent
# firewall-cmd --reload

これですべての問題点が解決できた事になります。